package com.supermarket.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.supermarket.entity.Commodity;
import com.supermarket.mapper.CommodityMapper;
import com.supermarket.common.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class CommodityService {

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private RedisUtil redisUtil;
    
    // Redis缓存相关的Key前缀
    private static final String COMMODITY_DETAIL_KEY = "commodity:detail:";
    private static final String COMMODITY_LIST_KEY = "commodity:list:";
    private static final String COMMODITY_HOT_KEY = "commodity:hot";
    private static final int COMMODITY_CACHE_SECONDS = 3600; // 默认缓存1小时

    /**
     * 新增商品
     *
     * @param commodity
     * @return
     */
    @Transactional
    public int addCommodity(Commodity commodity) {
        // 插入商品基本信息
        int result = commodityMapper.insert(commodity);
        
        if (result > 0 && commodity.getId() != null) {
            // 如果有分类标签，则插入分类标签
            if (commodity.getCategoryTag() != null && !commodity.getCategoryTag().isEmpty()) {
                // 先删除旧的标签（虽然新增商品不需要，但为了安全）
                commodityMapper.updateCategoryTags(commodity.getId());
                // 再插入新的标签
                commodityMapper.insertCategoryTags(commodity.getId(), commodity.getCategoryTag());
            }
            
            // 如果有图片，则插入图片
            if (commodity.getImage() != null && !commodity.getImage().isEmpty()) {
                // 先删除旧的图片（虽然新增商品不需要，但为了安全）
                commodityMapper.updateImages(commodity.getId());
                // 再插入新的图片
                commodityMapper.insertImages(commodity.getId(), commodity.getImage());
            }
            
            // 清除商品列表缓存
            clearCommodityListCache();
        }
        
        return result;
    }

    /**
     * 更新商品
     *
     * @param commodity
     * @return
     */
    @Transactional
    public int updateCommodity(Commodity commodity) {
        int result = commodityMapper.update(commodity);
        
        if (result > 0) {
            // 更新分类标签
            if (commodity.getCategoryTag() != null) {
                // 先删除旧的标签
                commodityMapper.updateCategoryTags(commodity.getId());
                // 再插入新的标签（如果有的话）
                if (!commodity.getCategoryTag().isEmpty()) {
                    commodityMapper.insertCategoryTags(commodity.getId(), commodity.getCategoryTag());
                }
            }
            
            // 更新图片
            if (commodity.getImage() != null) {
                // 先删除旧的图片
                commodityMapper.updateImages(commodity.getId());
                // 再插入新的图片（如果有的话）
                if (!commodity.getImage().isEmpty()) {
                    commodityMapper.insertImages(commodity.getId(), commodity.getImage());
                }
            }
            
            // 清除该商品的缓存
            clearCommodityCache(commodity.getId());
            // 清除商品列表缓存
            clearCommodityListCache();
        }
        
        return result;
    }

    /**
     * 更新分类Tags
     *
     * @param id
     * @param categoryTags
     * @return
     */
    @Transactional
    public int updateCategoryTags(Integer id, List<String> categoryTags) {
        // 先删除旧的标签
        commodityMapper.updateCategoryTags(id);
        
        // 再插入新的标签（如果有的话）
        if (categoryTags != null && !categoryTags.isEmpty()) {
            int result = commodityMapper.insertCategoryTags(id, categoryTags);
            
            // 清除该商品的缓存
            clearCommodityCache(id);
            // 清除商品列表缓存
            clearCommodityListCache();
            
            return result;
        }
        
        // 清除该商品的缓存
        clearCommodityCache(id);
        // 清除商品列表缓存
        clearCommodityListCache();
        
        return 1; // 删除成功即可
    }

    /**
     * 更新商品图片
     *
     * @param id
     * @param images
     * @return
     */
    @Transactional
    public int updateImages(Integer id, List<String> images) {
        // 先删除旧的图片
        commodityMapper.updateImages(id);
        
        // 再插入新的图片（如果有的话）
        if (images != null && !images.isEmpty()) {
            int result = commodityMapper.insertImages(id, images);
            
            // 清除该商品的缓存
            clearCommodityCache(id);
            
            return result;
        }
        
        // 清除该商品的缓存
        clearCommodityCache(id);
        
        return 1; // 删除成功即可
    }

    /**
     * 根据ID查询商品（集成Redis缓存）
     * 查询顺序：先查Redis缓存，未命中再查数据库并写入缓存
     * @param id 商品ID
     * @return 商品信息
     */
    public Commodity getCommodityById(Integer id) {
        String cacheKey = COMMODITY_DETAIL_KEY + id;
        // 1. 先查Redis缓存
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (Commodity) cached;
        }
        // 2. 未命中则查数据库
        Commodity commodity = commodityMapper.selectById(id);
        if (commodity != null) {
            // 3. 写入Redis缓存，设置过期时间
            redisUtil.set(cacheKey, commodity, COMMODITY_CACHE_SECONDS);
            
            // 4. 增加商品热度计数
            incrementCommodityHot(id);
        }
        return commodity;
    }

    /**
     * 条件查询商品
     *
     * @param name
     * @param status
     * @param categoryTag
     * @return
     */
    public List<Commodity> searchCommodities(String name, String status, List<String> categoryTag) {
        // 生成缓存key
        String cacheKey = generateListCacheKey(name, status, categoryTag);
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (List<Commodity>) cached;
        }
        
        // 缓存未命中，查询数据库
        List<Commodity> commodities = commodityMapper.selectByCondition(name, status, categoryTag);
        
        // 写入缓存
        if (commodities != null && !commodities.isEmpty()) {
            redisUtil.set(cacheKey, commodities, COMMODITY_CACHE_SECONDS);
        }
        
        return commodities;
    }

    /**
     * 分页条件查询商品
     *
     * @param pageNum 页码
     * @param pageSize 每页数量
     * @param name 商品名称
     * @param status 商品状态
     * @param categoryTag 分类标签
     * @param sortField 排序字段
     * @param sortOrder 排序顺序
     * @return 分页结果
     */
    public Map<String, Object> searchCommoditiesWithPage(int pageNum, int pageSize, String name, String status, List<String> categoryTag, String sortField, String sortOrder) {
        // 生成缓存key，拼接排序参数
        String cacheKey = generateListCacheKey(name, status, categoryTag, pageNum, pageSize) + ":sort:" + (sortField == null ? "" : sortField) + ":" + (sortOrder == null ? "" : sortOrder);
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (Map<String, Object>) cached;
        }
        // 使用 PageHelper 进行分页
        PageHelper.startPage(pageNum, pageSize);
        List<Commodity> commodities = commodityMapper.selectByConditionWithPage(name, status, categoryTag, sortField, sortOrder);
        // 获取分页信息
        PageInfo<Commodity> pageInfo = new PageInfo<>(commodities);
        // 构造返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", pageInfo.getList());
        result.put("total", pageInfo.getTotal());
        result.put("pageNum", pageInfo.getPageNum());
        result.put("pageSize", pageInfo.getPageSize());
        result.put("pages", pageInfo.getPages());
        // 写入缓存
        redisUtil.set(cacheKey, result, COMMODITY_CACHE_SECONDS);
        return result;
    }

    /**
     * 删除商品
     *
     * @param id 商品ID
     * @return 影响行数
     */
    @Transactional
    public int deleteCommodity(Integer id) {
        int result = commodityMapper.deleteById(id);
        
        if (result > 0) {
            // 清除该商品的缓存
            clearCommodityCache(id);
            // 清除商品列表缓存
            clearCommodityListCache();
            // 从热门商品中移除
            redisUtil.zrem(COMMODITY_HOT_KEY, id.toString());
        }
        
        return result;
    }

    /**
     * 查询商品总数
     * @return 商品总数
     */
    public int countCommodities() {
        // 尝试从缓存获取
        String cacheKey = "commodity:count";
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (int) cached;
        }
        
        // 缓存未命中，查询数据库
        int count = commodityMapper.countCommodities();
        
        // 写入缓存，设置较短的过期时间（5分钟）
        redisUtil.set(cacheKey, count, 300);
        
        return count;
    }
    
    /**
     * 获取热门商品列表
     * @param limit 获取数量
     * @return 热门商品列表
     */
    public List<Commodity> getHotCommodities(int limit) {
        // 从Redis的ZSet中获取热门商品ID列表
        Set<Object> hotIds = redisUtil.zrevrange(COMMODITY_HOT_KEY, 0, limit - 1);
        
        if (hotIds == null || hotIds.isEmpty()) {
            // 如果没有热门商品记录，则返回默认排序的商品
            return commodityMapper.selectByCondition(null, "1", null).subList(0, Math.min(limit, 10));
        }
        
        // 查询这些热门商品的详细信息
        List<Commodity> hotCommodities = new ArrayList<>();
        for (Object idObj : hotIds) {
            String idStr = (String) idObj;
            Integer id = Integer.parseInt(idStr);
            Commodity commodity = getCommodityById(id);
            if (commodity != null) {
                hotCommodities.add(commodity);
            }
        }
        
        return hotCommodities;
    }
    
    /**
     * 增加商品热度
     * @param id 商品ID
     */
    private void incrementCommodityHot(Integer id) {
        // 增加商品热度，每次查询+1
        redisUtil.zincrby(COMMODITY_HOT_KEY, id.toString(), 1);
    }
    
    /**
     * 清除指定商品的缓存
     * @param id 商品ID
     */
    private void clearCommodityCache(Integer id) {
        String cacheKey = COMMODITY_DETAIL_KEY + id;
        redisUtil.delete(cacheKey);
    }
    
    /**
     * 清除商品列表缓存
     * 使用通配符批量删除
     */
    private void clearCommodityListCache() {
        // 获取符合模式的所有键
        Set<String> keys = redisUtil.keys(COMMODITY_LIST_KEY + "*");
        if (keys != null && !keys.isEmpty()) {
            redisUtil.delete(keys);
        }
        
        // 清除商品计数缓存
        redisUtil.delete("commodity:count");
    }
    
    /**
     * 生成列表缓存Key
     */
    private String generateListCacheKey(String name, String status, List<String> categoryTag) {
        StringBuilder key = new StringBuilder(COMMODITY_LIST_KEY);
        key.append("name:").append(name == null ? "null" : name).append(":");
        key.append("status:").append(status == null ? "null" : status).append(":");
        key.append("category:");
        if (categoryTag != null && !categoryTag.isEmpty()) {
            for (String tag : categoryTag) {
                key.append(tag).append(",");
            }
        } else {
            key.append("null");
        }
        return key.toString();
    }
    
    /**
     * 生成分页列表缓存Key
     */
    private String generateListCacheKey(String name, String status, List<String> categoryTag, int pageNum, int pageSize) {
        return generateListCacheKey(name, status, categoryTag) + ":page:" + pageNum + ":" + pageSize;
    }
}